"""
头像相关接口路由 - 使用LeanCloud存储
"""

import os
import time
import io
from typing import Optional
from fastapi import APIRouter, Header, UploadFile, File
from fastapi.responses import JSONResponse
from PIL import Image, ImageOps
import leancloud
from model.message_model import Message
from utils.password_utils import get_user_id_from_jwt
from db.operations import UserOperations
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

# 初始化LeanCloud
# 请在这里替换为您的LeanCloud应用配置
leancloud.init(
    app_id=os.getenv("MY_APP_ID"),
    app_key=os.getenv("MY_APP_KEY"),
)


# 创建头像相关的子路由
router = APIRouter(
    prefix="/avatar",
    tags=["avatar"],
    responses={404: {"description": "Not found"}},
)

# 支持的图片格式
ALLOWED_EXTENSIONS = {".jpg", ".jpeg", ".png"}
ALLOWED_CONTENT_TYPES = {"image/jpeg", "image/jpg", "image/png"}

# 文件大小限制 (5MB)
MAX_FILE_SIZE = 5 * 1024 * 1024


@router.get("/", summary="头像管理接口信息")
async def get_avatar_info():
    """获取头像管理接口信息"""
    api_info = {
        "message": "头像管理API接口 - 使用LeanCloud存储",
        "endpoints": {
            "GET /api/avatar/": "获取头像管理接口信息",
            "POST /api/avatar/upload": "上传头像（需要认证）",
        },
        "file_requirements": {
            "formats": ["PNG", "JPG", "JPEG"],
            "max_size": "5MB",
            "output_size": "300x300px",
            "output_format": "JPEG",
            "compression_quality": "85%",
        },
        "storage_format": {
            "platform": "LeanCloud",
            "description": "文件存储在LeanCloud，通过url访问",
        },
        "examples": {
            "上传头像": {
                "url": "/api/avatar/upload",
                "method": "POST",
                "headers": {"Authorization": "Bearer your_token"},
                "content_type": "multipart/form-data",
                "description": "上传头像文件，自动压缩和调整大小，返回头像路径",
            }
        },
    }
    return JSONResponse(status_code=200, content=api_info)


def is_valid_image(file: UploadFile) -> bool:
    """验证是否为有效的图片文件"""
    if not file.content_type or file.content_type not in ALLOWED_CONTENT_TYPES:
        return False

    if file.filename:
        ext = os.path.splitext(file.filename)[1].lower()
        return ext in ALLOWED_EXTENSIONS

    return True


def compress_image(content: bytes) -> bytes:
    """
    压缩图片：调整大小并优化质量

    Args:
        content: 原始图片内容

    Returns:
        bytes: 压缩后的图片内容
    """
    try:
        image = Image.open(io.BytesIO(content))

        # 转换为RGB模式
        if image.mode != "RGB":
            image = image.convert("RGB")

        # 使用ImageOps.fit进行智能裁剪和缩放
        # 这个方法会自动居中裁剪并缩放到目标尺寸
        final_image = ImageOps.fit(
            image,
            (300, 300),  # 目标尺寸
            Image.Resampling.LANCZOS,  # 重采样方法
            centering=(0.5, 0.5),  # 居中裁剪 (0.5, 0.5)表示从中心裁剪
        )

        # 保存为JPEG
        output = io.BytesIO()
        final_image.save(output, format="JPEG", quality=85, optimize=True)
        return output.getvalue()

    except Exception as e:
        print(f"图片处理失败: {e}")
        return content


async def upload_to_leancloud(file_content: bytes, user_id: int) -> dict:
    """
    上传文件到LeanCloud

    Args:
        file_content: 文件内容
        user_id: 用户ID

    Returns:
        dict: 包含文件信息的字典 {'object_id': str, 'url': str}

    Raises:
        Exception: 上传失败时抛出异常
    """
    try:
        # 创建文件数据流
        file_stream = io.BytesIO(file_content)
        # 生成唯一的文件名
        timestamp = int(time.time())
        unique_filename = f"avatar_{user_id}_{timestamp}.jpg"
        # 创建LeanCloud文件对象
        lc_file = leancloud.File(unique_filename, file_stream)
        # 上传文件到LeanCloud
        lc_file.save()
        return {
            "object_id": lc_file.id,
            "url": lc_file.url,
            "filename": unique_filename,
        }

    except Exception as e:
        print(f"LeanCloud文件上传失败: {e}")
        raise Exception(f"文件上传失败: {str(e)}")


@router.post("/upload", summary="上传用户头像到LeanCloud")
async def upload_avatar(
    file: UploadFile = File(..., description="头像文件"),
    authorization: Optional[str] = Header(None, description="Bearer token"),
):
    """上传用户头像到LeanCloud存储"""
    # 去除Bearer前缀
    authorization = authorization.replace("Bearer ", "", 1) if authorization else None
    # 验证用户是否已登录
    user_id_from_jwt = await get_user_id_from_jwt(authorization)

    if not user_id_from_jwt:
        return JSONResponse(
            status_code=401,
            content=Message(message="未授权，请先登录").model_dump(),
        )
    # 验证文件类型
    if not is_valid_image(file):
        return JSONResponse(
            status_code=400,
            content=Message(message="只支持 PNG, JPG, JPEG 格式的图片").model_dump(),
        )
    # 验证文件大小
    if file.size and file.size > MAX_FILE_SIZE:
        return JSONResponse(
            status_code=400,
            content=Message(message="文件大小不能超过 5MB").model_dump(),
        )
    try:
        # 读取文件内容
        content = await file.read()
        # 压缩图片
        compressed_content = compress_image(content)
        # 上传到LeanCloud
        file_info = await upload_to_leancloud(compressed_content, user_id_from_jwt)
        # 更新数据库 - 存储LeanCloud的objectId
        user_ops = UserOperations()
        update_data = {
            "user_id": user_id_from_jwt,
            "avatar_url": file_info["url"],
            "updated_at": int(time.time()),
        }
        update_result = await user_ops.batch_update_users([update_data])
        if update_result > 0:
            return JSONResponse(
                status_code=200,
                content={"message": "头像上传成功", "avatar_url": file_info["url"]},
            )
        else:
            return JSONResponse(
                status_code=500,
                content=Message(message="头像上传失败，请稍后再试").model_dump(),
            )
    except Exception as e:
        print(f"头像上传异常: {e}")
        return JSONResponse(
            status_code=500,
            content=Message(message=f"上传失败: {str(e)}").model_dump(),
        )
